package com.its.us.sk.server.ws.base;

import com.its.us.sk.server.ws.config.NettyWsConfig;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

import java.net.URLEncoder;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collection;

/**
 * @Author: master
 * @Date: 2020/11/1 19:45
 * @Version: 1.0
 */
public abstract class BaseWebSocketHandler extends BaseWebPushHandler {

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        //System.err.println("服务器端收到消息：" + msg.text());
        // 回复消息
        //ctx.channel().writeAndFlush(new TextWebSocketFrame("服务器时间：" + LocalDateTime.now() + " " + msg.text()));
        this.write(ctx,msg);
    }

    protected  abstract void write(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception;

    /**
     * 一旦链接，第一个被执行
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        // channelGroup.writeAndFlush 会遍历并将消息发送 不需要自己遍历
        NettyWsConfig.getChannelGroup().writeAndFlush("ws客户端：【" + ctx.channel().remoteAddress() + "】加入了！时间：" + nowTime);
        NettyWsConfig.getChannelGroup().add(ctx.channel());
        System.err.println("ws人数：" + NettyWsConfig.getChannelGroup().size());
        String msg = "【ws客户端：" + ctx.channel().remoteAddress() + "】欢迎连接！时间：" + nowTime.getBytes();
        ctx.writeAndFlush(URLEncoder.encode(msg, "UTF-8"));
    }

    /**
     * 处于活动状态
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.err.println("ws:"+ctx.channel().remoteAddress() + "：上线了！时间：" + nowTime);
    }

    /**
     * 处于非活动状态
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        System.err.println("ws:"+ctx.channel().remoteAddress() + "：离线了！时间：" + nowTime);
        System.err.println("ws channelGroup size:" + NettyWsConfig.getChannelGroup().size());
    }


    /**
     * 断开连接
     *
     * @param ctx
     * @throws Exception
     */
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        String nowTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        NettyWsConfig.getChannelGroup().writeAndFlush("ws客户端：【" + channel.remoteAddress() + "】离开了！时间：" + nowTime);
        // 一旦触发此事件，会自动将 channelGroup 中的channel remove 掉
        Collection<Channel> col = NettyWsConfig.getUserChannelMap().values();
        while (true == col.contains(ctx.channel())) {
            col.remove(ctx.channel());
            System.err.println("netty 客户端移除成功");
        }
        System.err.println("userChannel 人数：" + NettyWsConfig.getUserChannelMap().size());
    }

    /**
     * 发生异常自动关闭通道
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        System.err.println("异常发生：" + cause);
        ctx.close();
    }
}
